package utils

import (
	"context"
	"fmt"
	"github.com/go-redis/redis/v8"
	"github.com/spf13/viper"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
	"log"
	"os"
	"time"
)

var (
	DB    *gorm.DB
	Redis *redis.Client
)

type MySQLConfig struct {
	User     string
	Password string
	Host     string
	Port     string
	DBName   string
}

func InitConfig() {
	viper.SetConfigName("app")
	viper.AddConfigPath("config")
	err := viper.ReadInConfig()
	if err != nil {
		panic(err)
	}
	fmt.Println("--------------Config app invited--------------")
	fmt.Println("config mysql:", viper.Get("mysql"))
	fmt.Println("config redis:", viper.Get("redis"))
}

func InitMysql() {
	newLogger := logger.New(
		log.New(os.Stdout, "\r\n", log.LstdFlags),
		logger.Config{
			SlowThreshold: time.Second,
			LogLevel:      logger.Info,
			Colorful:      true,
		})

	// DB, _ = gorm.Open(mysql.Open(viper.GetString("mysql.dns")), &gorm.Config{})
	//if err != nil { panic("failed to connect database") }
	mysqlConfig := MySQLConfig{
		User:     viper.GetString("mysql.user"),
		Password: viper.GetString("mysql.password"),
		Host:     viper.GetString("mysql.host"),
		Port:     viper.GetString("mysql.port"),
		DBName:   viper.GetString("mysql.dbname"),
	}
	dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",
		mysqlConfig.User,
		mysqlConfig.Password,
		mysqlConfig.Host,
		mysqlConfig.Port,
		mysqlConfig.DBName,
	)
	var err error
	DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{Logger: newLogger})
	if DB != nil {
		fmt.Println("--------------MySQL invited--------------")
	} else {
		log.Fatalf("Could not connect to MySQL: %v", err)
	}
}

func InitRedis() {
	Redis = redis.NewClient(&redis.Options{
		Addr:         viper.GetString("redis.addr"),
		Password:     viper.GetString("redis.password"),
		DB:           viper.GetInt("redis.DB"),
		PoolSize:     viper.GetInt("redis.poolSize"),
		MinIdleConns: viper.GetInt("redis.minIdleConns"),
	})

	ctx := context.Background()
	pong, err := Redis.Ping(ctx).Result()
	if err != nil {
		log.Fatalf("Could not connect to Redis: %v", err)
	}
	if pong == "PONG" {
		fmt.Println("--------------Redis connected--------------")
	}
}

const (
	PublishKey = "websocket"
)

// Publish 发布消息到redis
func Publish(ctx context.Context, channel string, message string) error {
	var err error
	fmt.Println("--------------Publish--------------", message)
	err = Redis.Publish(ctx, channel, message).Err()
	return err
}

// Subscribe 订阅redis消息
func Subscribe(ctx context.Context, channel string) (string, error) {
	subscribe := Redis.Subscribe(ctx, channel)
	message, err := subscribe.ReceiveMessage(ctx)
	fmt.Println("--------------subscribe--------------", message)
	return message.Payload, err
}
